﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Security;
using EnvironmentConfigGenerator;

namespace EnvironmentConfigGenerator
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ValidateInputParams(args);
                string currentPath = Environment.CurrentDirectory;
                string xmlFilePath = args[0];
                string templateConfigPath = args[1];
                string filesDestinaionPath = args.Count() > 2 ? args[2] : string.Empty;

                if (!Path.IsPathRooted(xmlFilePath))
                {
                    xmlFilePath = Path.Combine(currentPath, xmlFilePath);
                }

                if (!Path.IsPathRooted(templateConfigPath))
                {
                    templateConfigPath = Path.Combine(currentPath, templateConfigPath);
                }

                if (string.IsNullOrEmpty(filesDestinaionPath))
                {
                    filesDestinaionPath = Path.GetDirectoryName(templateConfigPath);
                }

                GenerateConfigFiles(xmlFilePath, templateConfigPath, filesDestinaionPath);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        public static void GenerateConfigFiles(string xmlFilePath, string templateConfigPath, string filesDestinaionPath)
        {
            if(System.IO.File.Exists(xmlFilePath))
            {
                Stream xmlStream = System.IO.File.OpenRead(xmlFilePath);
                StreamReader streamReader = null;

                if (xmlStream != null)
                {
                    streamReader = new StreamReader(xmlStream);
                }
                else
                {
                    Console.WriteLine(Constants.UnableToLoadTemplate);
                }
                
                XmlSerializer serializer = new XmlSerializer(typeof(Files));
                Files ouputFiles = serializer.Deserialize(streamReader) as Files;

                foreach(File file in ouputFiles.OutputFiles)
                {
                    string destFile = Path.Combine(filesDestinaionPath, file.Name);

                    System.IO.File.Copy(templateConfigPath, destFile, true);
                    ReplaceLineByLine(destFile, file.NameValuePairs);
                }
            }
            else
            {
                Console.WriteLine(Constants.XMSourceNotExists);
            }
        }

        public static void ValidateInputParams(string[] args)
        {
            if (args.Count() < 2)
            {
                Console.WriteLine(Constants.InvalidArguments);
            }
        }

        public static void ReplaceLineByLine(string filePath, NameValuePair[] withText)
        {
            string tmpFilePath = filePath + Constants.TmpExtension;
            StreamReader streamReader = new StreamReader(filePath);
            StreamWriter streamWriter = new StreamWriter(tmpFilePath);

            while (!streamReader.EndOfStream)
            {
                string data = streamReader.ReadLine();
                foreach(NameValuePair pair in withText)
                {
                    string valText = SecurityElement.Escape(pair.Value);
                    data = data.Replace(pair.Name, valText);
                }
                streamWriter.WriteLine(data);
            }
            streamReader.Close();
            streamWriter.Close();

            System.IO.File.Delete(filePath);
            System.IO.File.Move(tmpFilePath, filePath);
        }
    }
}
